home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
map_grid.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
18KB
|
468 lines
; $Id: map_grid.pro,v 1.19 1997/03/26 00:15:35 dave Exp $
;
; Copyright (c) 1996-1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;+
; NAME:
; MAP_GRID
;
; PURPOSE:
; The MAP_GRID procedure draws the graticule of parallels and meridians,
; according to the specifications established by MAP_SET. MAP_SET must be called
; before MAP_GRID to establish the projection type, the center of the
; projection, polar rotation and geographical limits.
;
; CATEGORY:
; Mapping.
;
; CALLING SEQUENCE:
; MAP_GRID
;
; INPUTS:
; NONE
;
; OPTIONAL INPUTS:
; NONE
;
; KEYWORD PARAMETERS:
;
; CHARSIZE: The size of the characters used for the labels. The default is 1.
; COLOR: The color index for the grid lines.
;FILL_HORIZON: Fills the current map_horizon.
; HORIZON: Draws the current map horizon.
; INCREMENT: Determines the spacing between graticle points.
; GLINESTYLE: If set, the line style used to draw the grid of parallels and
; meridians. See the IDL User's Guide for options. The default is
; dotted.
; GLINETHICK: The thickness of the grid lines. Default is 1.
; LABEL: Set this keyword to label the parallels and meridians with their
; corresponding latitudes and longitudes. Setting this keyword to
; an integer will cause every LABEL gridline to be labeled (i.e,
; if LABEL=3 then every third gridline will be labeled). The
; starting point for determining which gridlines are labeled is the
; minimum latitude or longitude (-180 to 180), unless the LATS or
; LONS keyword is set to a single value. In this case, the starting
; point is the value of LATS or LONS.
; LATALIGN: This keyword controls the alignment of the text baseline for
; latitude labels. A value of 0.0 left justifies the label,
; 1.0 right justifies it, and 0.5 centers it.
; LATDEL: The spacing in degrees between parallels of latitude in the grid.
; If not set, a suitable value is determined from the current map
; projection.
; LATS: The desired latitudes to be drawn (and optionally labeled). If
; this keyword is omitted, appropriate latitudes will be generated
; with consideration of the optional LATDEL keyword. If this
; keyword is set to a single value, drawn (and optionally labeled)
; latitudes will be automatically generated as
; [...,LATS-LATDEL,LATS,LATS+LATDEL,...] over the extent of the
; map. The single valued LATS is taken to be the starting point
; for labelling (See the LABEL keyword).
; LATLAB: The longitude at which to place latitude labels. The default is
; the center longitude on the map.
; LATNAMES: An array specifing the names to be used for the latitude labels.
; By default, this array is automatically generated in units of
; degrees. This array can be a string array or numeric, but should
; not be of mixed type. When LATNAMES is specified, LATS must also
; be specified, but the number of elments in the two arrays need not
; be equal. Extra LATNAMES are ignored, while LATNAMES not supplied
; are automatically reported in degrees. LATNAMES can be used when
; LATS is set to a single value. It this case, the LATS used will
; start at the specified latitude and progress northward, wrapping
; around the globe if appropriate. Caution should be used when
; using LATNAMES in conjunction with a single LATS, since the
; number of visible latitude gridlines is dependent on many factors.
; LONALIGN: This keyword controls the alignment of the text baseline for
; longitude labels. A value of 0.0 left justifies the label,
; 1.0 right justifies it, and 0.5 centers it.
; LONDEL: The spacing in degrees between meridians of longitude in the grid.
; If not set, a suitable value is determined from the current map
; projection.
; LONLAB: The latitude at which to place longitude labels. The default is
; the center latitude on the map.
; LONS: The desired longitudes to be drawn (and optionally labeled). If
; this keyword is omitted, appropriate longitudes will be generated
; with consideration of the optional LONDEL keyword. If this
; keyword is set to a single value, drawn (and optionally labeled)
; longitudes will be automatically generated as
; [...,LONS-LONDEL,LONS,LONS+LONDEL,...] over the extent of the map.
; The single valued LONS is taken to be the starting point for
; labeling (See the LABEL keyword).
; LONNAMES: An array specifing the names to be used for the longitude labels.
; By default, this array is automatically generated in units of
; degrees. This array can be a string array or numeric, but should
; not be of mixed type. When LONNAMES is specified, LATS must also
; be specified, but the number of elments in the two arrays need not
; be equal. Extra LONNAMES are ignored, while LATNAMES not supplied
; are automatically reported in degrees. LONNAMES can be used when
; LONS is set to a single value. It this case, the LONS used will
; start at the specified longitude and progress eastward, wrapping
; around the globe if appropriate. Caution should be used when
; using LONNAMES in conjunction with a single LONS, since the number
; of visible longitude gridlines is dependent on many factors.
;ORIENTATION: Specifies the clockwise angle in degrees from horizontal
; of the text baseline that the labels should be rotated. Note,
; that the rotation used in MAP_SET is also clockwise, but XYOUTS
; is normally counterclockwise.
;OUTPUTS:
; Draws gridlines and labels on the current map.
;
; EXAMPLE:
; map_set,10,20,23.5,/cont,/ortho,/horizon ; establish a projection
; lats=[-65,-52,-35,-20,-2.59,15,27.6,35,45,55,75,89]
; ; choose the parallels to draw
; map_grid,lats=lats,londel=20,lons=-13,label=2,lonlab=-2.5,latlab=7
; ;draw the grid
;
; MODIFICATION HISTORY:
; Written by: SVP, May, 23 1996.
; DMS, Feb, 1996 Note that this version plots all gridlines
; unless a 4 element LIMIT was specified to MAP_SET.
; SVP, Nov 1996 Changed over !map1 (new IDL5 maps)
; SVP, May 1996 Map_Grid used to live inside of map_set.pro, now
; it lives here.
; SVP, May 1996 Changed LABEL to determine the skip between labelled
; gridlines.
; Also, added the LATS and LONS keywords to give complete
; control over where the labels go.
; SVP, Sept 1996 Added LATNAMS,LONAMES, and ORIENTATION keywords
; DMS, Nov, 1996 Rev 2 of maps.
;-
function map_grid_incr, span
;
; Determine LONDEL or LATDEL if not specified
;
IF span eq 0 THEN return, 45.
ipow = 0
t = span < 450.
WHILE t lt 5 DO BEGIN t = t * 10 & ipow = ipow +1 & ENDWHILE
increments = [ 1., 2., 4., 5., 10., 15., 30., 45.]
i = 0
WHILE t gt (increments[i] * 10) DO i = i + 1
return, increments[i] / 10^ipow
end
PRO map_grid, label=label, latdel = latdel, no_grid=no_grid, $
londel=londel, glinestyle=glinestyle, glinethick=glinethick, $
lonlab=lonlab, latlab=latlab, lonalign=lonalign, $
latalign=latalign, lonnames=lonnames, latnames=latnames, $
whole_map=whole_map, lats=lats, lons=lons, zvalue=zvalue, $
color=color, t3d=t3d, charsize=charsize, orientation=orientation, $
horizon=horizon, fill_horizon=fill_horizon, _EXTRA=extra, $
increment=increment
;
; Put a grid on a previously established map projection.
;
; no grid? - in case someone wants just to put labels
no_grid = keyword_set(no_grid)
;
; if Label = n, then Labels are added every n gridlines
;
if n_elements(label) THEN nlabel=fix(abs(label[0])) ELSE nlabel=0
have_lons = keyword_set(lons)
have_lats = keyword_set(lats)
have_lonnames = keyword_set(lonnames)
have_latnames = keyword_set(latnames)
if n_elements(zvalue) eq 0 THEN zvalue = 0
; Append the graphics keywords:
if n_elements(t3d) then map_struct_append, extra,'T3D',t3d
if n_elements(color) then map_struct_append, extra, 'COLOR',color
if n_elements(glinestyle) eq 0 then glinestyle = 1 ;Default = dotted
map_struct_append, extra, 'LINESTYLE', glinestyle ;Append it
if n_elements(glinethick) then map_struct_append, extra,'THICK',glinethick
if n_elements(charsize) then map_struct_append, extra,'CHARSIZE',charsize
if n_elements(orientation) then $ ;Orientation is reversed...
map_struct_append, extra,'ORIENTATION', -1 * orientation
;
; The gridlines can be specified by
;
; 1) an array of lats and/or lons
; 2) a single lats or lons which is taken to be the center
; or 'for sure' lat or lon with gridlines every latdel or londel from it
; 3) automatically calculated if lats or lons are not specified.
;
if (!x.type NE 3) THEN $ ; make sure we have mapping coordinates
message, 'map_grid---Current ploting device must have mapping coordinates'
;
; Require that LATS be specified when LATNAMES is ALSO SPECIFIED
;
if have_latnames and not(have_lats) then $
message,'map_grid---The LATNAMES keyword MUST be used in conjuction '+$
'with the LATS keyword.'
;
; Same for lons
;
if have_lonnames and not(have_lons) then $
message,'map_grid---The LONNAMES keyword MUST be used in conjuction '+$
'with the LONS keyword.'
; Get lat/lon ranges from !MAP. Did MAP_SET specify 4 element limit?
if !map.ll_box(0) ne !map.ll_box(2) or $
!map.ll_box(1) ne !map.ll_box(3) then begin
lonmin = !map.ll_box(1) & lonmax = !map.ll_box(3) & lonmax1 = lonmax
latmin = !map.ll_box(0) & latmax = !map.ll_box(2)
endif else begin ;If not, use entire globe
lonmin = -180 & lonmax1 = (lonmax = 180)
latmin = -90 & latmax = 90
endelse
IF lonmax1 le lonmin THEN lonmax1 = lonmax1 + 360.
;Default grid spacings...
IF n_elements(latdel) eq 0 THEN begin
latdel = map_grid_incr(latmax-latmin)
latd = 1
endif else latd = latdel
IF n_elements(londel) eq 0 THEN begin
londel = map_grid_incr(lonmax1-lonmin)
lond = 1
endif else lond = londel
; IF WHOLE_MAP specified, or the deltas are < 1,
; do not convert the limits into integers
IF (not keyword_set(whole_map)) THEN BEGIN
IF abs(latmax - latmin) gt 5. and latd ge 1 THEN BEGIN ;Make range integers
latmin = float(floor(latmin))
latmax = ceil(latmax)
ENDIF
IF abs(lonmax1 - lonmin) gt 5 and lond ge 1 THEN BEGIN
lonmin = float(floor(lonmin))
lonmax1 = ceil(lonmax1)
ENDIF
ENDIF
IF N_Elements(label) NE 0 OR N_ELEMENTS(Latlab) ne 0 OR $
N_Elements(LonLab) NE 0 THEN BEGIN
IF N_Elements(Latlab) eq 0 THEN Latlab = (lonmin + lonmax1)/2
IF N_ELements(LonLab) eq 0 THEN LonLab = (latmin +latmax)/2
ENDIF
; of grid numbers
IF n_elements(latalign) eq 0 THEN latalign = .5 ;Text alignment of lat labels
IF n_elements(lonalign) eq 0 THEN lonalign = .5 ;Text alignment of lon labels
;
map_proj_info, iproj, CYLINDRICAL=is_cyl, /CURRENT
if keyword_set(increment) then step=increment $
else step = 4 < (latmax - latmin)/10.
len = long(float((latmax-latmin)) / float(step) + 1.0)
lati = (float(latmax-latmin) / (len-1.)) * findgen(len) + latmin ;lats
; This fudge avoids curved meridians at the poles because of the split planes
if is_cyl and !map.p0lat eq 0 then begin
del = 2.0e-2
if lati(0) eq -90 then lati(0) = del - 90.
if lati(len-1) eq 90 then lati(len-1) = 90. - del
endif
First = 1
;
; Determine the number of lons and the lon array
;
CASE n_elements(lons) OF
0: BEGIN
n_lons=1+fix((lonmax1-lonmin)/londel)
longitudes=lonmin+findgen(n_lons)*londel
ENDCASE
1: BEGIN
n_lons=1+fix((lonmax1-lonmin)/londel)
longitudes=lons[0]+(findgen(n_lons)-n_lons/2)*londel
index=where(longitudes eq lons[0])
longitudes=shift(longitudes,-1*index[0])
ENDCASE
ELSE: BEGIN
n_lons=n_elements(lons)
longitudes=lons
ENDCASE
ENDCASE
;
; Build the Longitude Label Flag
;
CASE nlabel OF
0: lon_label = bytarr(n_lons)
ELSE: BEGIN
lon_label=bytarr(n_lons)
CASE n_elements(lons) OF
1: BEGIN
; Make sure the center one is set and go out from there
index=where(longitudes eq lons[0])
i=index[0] ; Go Up
WHILE (i LE n_lons-1) DO BEGIN
lon_label[i]=1
i=i+nlabel
END
; Go Down
i=index[0]-nlabel
WHILE (i GE 0) DO BEGIN
lon_label[i]=1
i=i-nlabel
ENDWHILE
ENDCASE
ELSE: BEGIN
; Start with lonmin and label each nlabel point
i=0
WHILE (i LE n_lons-1) DO BEGIN
lon_label[i]=1
i=i+nlabel
END
END
ENDCASE
END
ENDCASE
;
; Dont repeat 180 labelling if the projection is cylindrical and
; Both 180 and -180 are present. This can be defeated by using
; LONS=-180
;
if is_cyl then begin
id_180 = where(longitudes eq 180,count)
id_m180 = where(longitudes eq -180,mcount)
if count gt 0 and mcount gt 0 then begin
if n_elements(lons) eq 1 then begin
if lons[0] eq -180 then lon_label[id_180]=0
endif else lon_label[id_m180]=0
endif
endif
; Do horizon if specified.
if keyword_set(horizon) then map_horizon, _EXTRA=e
if keyword_set(fill_horizon) then map_horizon, _EXTRA=e, /FILL
;
; Draw/Label the meridians
;
FOR i=0,n_lons-1 DO BEGIN
lon=longitudes[i]
IF (lon lt -180) THEN lon2 = lon + 360 $
ELSE IF (lon gt 180) THEN lon2 = -360 +lon $
ELSE lon2 = lon
IF no_grid eq 0 THEN PLOTS, lon, lati, zvalue, $
NOCLIP=0, _EXTRA=extra
IF lon2 ne long(lon2) THEN fmt = '(f7.2)' ELSE fmt = '(i4)'
IF lon_label[i] THEN BEGIN
lonname=strtrim(string(lon2, format=fmt),2)
;
; replace lonname if a user specified value is available
;
IF have_lonnames then $
IF i le n_elements(lonnames)-1 then $
IF (reverse(size(lonnames[i])))[1] eq 7 then $
lonname=lonnames[i] else $
lonname=strtrim(string(lonnames[i],format=fmt),2)
XYOUTS, lon, LonLab, ALIGNMENT=lonalign,lonname, NOCLIP=0, $
Z=zvalue, _EXTRA=extra
ENDIF
ENDFOR
step = 4 < (lonmax1 - lonmin)/10.
len = (lonmax1-lonmin)/step + 1
loni = findgen(len)*step + lonmin
IF (loni[len-1] NE lonmax1) THEN BEGIN
loni = [loni, lonmax1]
len = len + 1
ENDIF
;
; Determine the number of lats and the lat array
;
CASE n_elements(lats) OF
0: BEGIN
n_lats=1+fix((latmax-latmin)/latdel)
latitudes=latmin+findgen(n_lats)*latdel
END
1: BEGIN
n_lats=1+fix((latmax-latmin)/latdel)
latitudes=lats[0]+(findgen(n_lats)-n_lats/2)*latdel
index=where(latitudes eq lats[0])
latitudes=shift(latitudes,-1*index[0])
END
ELSE: BEGIN
n_lats=n_elements(lats)
latitudes=lats
END
ENDCASE
;
; Build the Longitude Label Flag
;
CASE nlabel OF
0: lat_label=bytarr(n_lats) > 0
ELSE: BEGIN
lat_label=bytarr(n_lats) > 0
CASE n_elements(lats) OF
1: BEGIN
; Make sure the center one is set
; and go out from there
;
index=where(latitudes eq lats[0],count)
; Go Up
i=index[0]
WHILE (i LE n_lats-1) DO BEGIN
lat_label[i]=1
i=i+nlabel
END
; Go Down
i=index[0]-nlabel
WHILE (i GE 0) DO BEGIN
lat_label[i]=1
i=i-nlabel
END
END
ELSE: BEGIN
; Start with latmin and label each nlabel point
;
i=0
WHILE (i LE n_lats-1) DO BEGIN
lat_label[i]=1
i=i+nlabel
END
END
ENDCASE
END
ENDCASE
;
; Draw/Label the parallels of latitude
;
FOR i=0,n_lats-1 DO BEGIN
lat=latitudes[i]
IF lat ne long(lat) THEN fmt = '(f7.2)' ELSE fmt = '(i4)'
IF lat_label[i] THEN BEGIN
latname=strtrim(string(lat, format=fmt),2)
;
; replace latname if a user specified value is available
;
IF have_latnames then $
IF i le n_elements(latnames)-1 then $
IF (reverse(size(latnames[i])))[1] eq 7 then $
latname=latnames[i] else $
latname=strtrim(string(latnames[i],format=fmt),2)
XYOUTS, latlab, lat, latname, alignment=latalign, NOCLIP=0, $
Z=zvalue, _EXTRA=extra
ENDIF
IF (no_grid eq 0) and (abs(lat) ne 90) THEN PLOTS, loni, lat, zvalue, $
NOCLIP=0, _EXTRA=extra
ENDFOR
end